//! # Deref Trait
//!
//! ```
//! pub trait Deref {
//!     type Target: ?Sized;
//!
//!     //Required method
//!     fn deref(&self) -> &Self::Target;
//! }
//! ```
//!

#![allow(dead_code)]
struct DerefLrn {}

impl DerefLrn {
    pub fn hello() {
        println!("Deref learning!");
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn impl_deref() {
        use std::ops::{Deref, DerefMut};

        struct DerefMutExample<T> {
            value: T,
        }

        impl<T> Deref for DerefMutExample<T> {
            type Target = T;

            fn deref(&self) -> &Self::Target {
                &self.value
            }
        }

        impl<T> DerefMut for DerefMutExample<T> {
            fn deref_mut(&mut self) -> &mut Self::Target {
                &mut self.value
            }
        }

        let mut x = DerefMutExample { value: 'a' };
        assert_eq!('a', *x);
        *x = 'b';
        assert_eq!('b', x.value);
    }

    #[test]
    fn test_deref_operator() {
        // NOTE: * 当应用于指针上时，它表示该指针指向的内存位置。
        // NOTE: 如果表达式类型为&mut T 或 *mut T，则他代表的内存位置可以被赋值。
        let x = &7;
        assert_eq!(*x, 7);
        let y = &mut 9;
        *y = 11;
        assert_eq!(*y, 11);
    }
}
